
require 'mysql'

module Ph

	module Driver

	class MySQL < Mysql

		module Engine
			MYISAM = "MYISAM"
		end

		TYPES = { :id => "INT", :string => "VARCHAR", :text => "TEXT", :date => 'INT', :int => 'INT', :double => 'DOUBLE' }

		def create(obj)
			case obj
			when Ph::Table
				self.query(self.generate_table_sql(obj))
			when Ph::Database
				self.query("CREATE SCHEMA IF NOT EXISTS #{obj.name}")
			else
				raise ArgumentError.new("Invalid Object: #{obj.class}.")
			end
		end

		def to_mysql_type(field)
			
			result = Ph::Driver::MySQL::TYPES[field[:type]]
			if (field[:decimal]) then
				result += "(#{field[:size]}, #{field[:decimal]})"
			else
				result += "(#{field[:size]})" if field[:size]
			end

			(result += ' AUTO_INCREMENT NOT NULL PRIMARY KEY') if (field[:auto])
				
			return result
		end

		# TODO fix engine
		def generate_table_sql(table)

			db 			= table.database
			record	= table.record
#			fields  = (record.fields.collect { |f| %{`#{f[:name]}` #{self.to_mysql_type(f)}} }).join(",\n") 
			fields  = (record.collect { |name, f| %{`#{name}` #{self.to_mysql_type(f)}} }).join(",\n") 
			engine  = @engine ? @engine : Ph::Driver::MySQL::Engine::MYISAM
 
			%{
				CREATE TABLE IF NOT EXISTS #{db.name}.#{table.name} (
					#{fields}
				) ENGINE = #{engine}
			}
		end

		def drop(obj)
			case obj
			when Ph::Table
				self.query("DROP TABLE IF EXISTS #{obj.database.name}.#{obj.name}")
			when Ph::Database
				self.query("DROP DATABASE IF EXISTS #{obj.name}")
			else
				raise ArgumentError.new("Invalid Object: #{obj.class}.")
			end
		end

		def select(table, where=nil)

			fields = table.record.keys.join(',')
			sql = 	("SELECT #{fields} FROM #{table.database.name}.#{table.name}") + \
					(where ? " WHERE (#{where})" : '')
			result = self.query(sql)

			response = {'total' => 0, 'found' => result.num_rows(), 'result' => Array.new}
			result.each_hash { |r| response['result'].push(r) }

			# TODO add more formats, add new Format class
			return response.to_json

		end

		# table is the Ph::Table object
		# data  is an array of Hash objects
		# TODO This is probably way too ineficient
		def insert(table, data)

			data.each do |r|
				
				values = 	(r.collect { |k, v| "#{k}=\"#{v}\"" }).join(',')
				
				query = "INSERT INTO #{table.database.name}.#{table.name} SET #{values}"
				result = self.query(query)
			end

		end

	end
	
	end # Module Driver

end # Module Ph
